package com.golxen.utils;


import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 字符串辅助类
 */
public class StringUtils {

	@SuppressWarnings("serial")
	private static final Set<Character.UnicodeBlock> mJapaneseUnicodeBlocks = new HashSet<Character.UnicodeBlock>() {
		{
			add(Character.UnicodeBlock.HIRAGANA);
			add(Character.UnicodeBlock.KATAKANA);
			add(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS);
		}
	};

	public static String clearHeadAndTailEmpty(String str) {
		str = str.trim();
		while (str.startsWith("　")) {// 这里判断是不是全角空格
			str = str.substring(1, str.length()).trim();
		}
		while (str.endsWith("　")) {
			str = str.substring(0, str.length() - 1).trim();
		}
		str = str.replaceAll("\n", " ");
		return str;
	}

	public static String getMsgString(String... values) {
		return listToString(Arrays.asList(values), '|');
	}

	/**
	 * list加分隔符转string
	 */
	public static String listToString(List<?> list, char separator) {

		if (null == list) {
			return "";
		}
		if (list.size() == 0) {
			return "";
		}

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			sb.append(list.get(i)).append(separator);
		}
		if (sb.toString().length() == 0) {
			return "";
		}
		return sb.toString().substring(0, sb.toString().length() - 1);
	}

	/**
	 * list加分隔符转string
	 */
	public static String listToString(List<?> list, String separator) {
		if (null == list) {
			return "";
		}
		if (list.size() == 0) {
			return "";
		}

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			sb.append(list.get(i)).append(separator);
		}
		if (sb.toString().length() == 0) {
			return "";
		}
		return sb.toString().substring(0, sb.toString().length() - separator.length());
	}

	public static List<BigInteger> stringToBigIntegerList(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new ArrayList<>();
		}
		List<BigInteger> result = new ArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(new BigInteger(str));
			}
		}
		return result;
	}

	public static List<Long> stringToLongList(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new ArrayList<>();
		}
		List<Long> result = new ArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(string2longSafe(str, 0));
			}
		}
		return result;
	}

	public static List<Long> stringToLongListOnConcurrent(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new CopyOnWriteArrayList<>();
		}
		List<Long> result = new CopyOnWriteArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(string2longSafe(str, 0));
			}
		}
		return result;
	}
	
	
	public static List<Integer> stringToIntegerList(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new ArrayList<>();
		}
		List<Integer> result = new ArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(string2intSafe(str, 0));
			}
		}
		return result;
	}
	
	public static List<Integer> stringToIntegerListOnConcurrent(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new CopyOnWriteArrayList<>();
		}
		List<Integer> result = new CopyOnWriteArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(string2intSafe(str, 0));
			}
		}
		return result;
	}

	public static LinkedList<Integer> stringToIntegerLinkedListNoZero(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new LinkedList<>();
		}
		LinkedList<Integer> result = new LinkedList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				int value = string2intSafe(str, 0);
				if (value > 0) {
					result.addLast(value);
				}
			}
		}
		return result;
	}

	public static List<Integer> stringToIntegerListNoZero(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new ArrayList<>();
		}
		List<Integer> result = new ArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				int value = string2intSafe(str, 0);
				if (value > 0) {
					result.add(value);
				}
			}
		}
		return result;
	}

	public static List<String> stringToStringList(String srcStr, String separator) {
		String[] strings = srcStr.split(separator);
		if (strings.length == 1 && isNullOrEmpty(strings[0])) {
			return new ArrayList<>();
		}
		List<String> result = new ArrayList<>();
		for (String str : strings) {
			if (!isNullOrEmpty(str)) {
				result.add(str);
			}
		}

		return result;
	}


	/**
	 * 判断字符串是否超过最大长度
	 * 
	 * @param rawStr
	 * @param maxLen
	 * @return
	 */
	public static String verifyMaxLen(String rawStr, int maxLen) {
		if (rawStr == null || rawStr.trim().length() == 0) {
			return rawStr;
		}
		if (rawStr.length() > maxLen) {
			return rawStr.substring(0, maxLen);
		}
		return rawStr;
	}

	/**
	 * 判断字符串是否为 null 或者 空串
	 */
	public static boolean isNullOrEmpty(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * 是否为数字类型(负数返回false)
	 */
	public static boolean isNumber(String str) {
		if (str.matches("\\d*")) {
			return true;
		} else {
			return false;
		}
	}

	public static int parseInt(String str) {
		if (isNullOrEmpty(str) || !isNumber(str)) {
			return 0;
		}
		return Integer.parseInt(str);
	}

	/**
	 * 判断指定字符串是否包含空白字符，包括\\s*|\t|\r|\n
	 */
	public static boolean containWhitespace(String str) {
		if (str == null || str.isEmpty()) {
			return false;
		}

		char[] data = str.toCharArray();
		for (char i : data) {
			if (Character.isWhitespace(i)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * 获取字符串长度(中文计算两个长度)
	 */
	public static int getStringLen(String str) {
		int len = 0;
		if (str == null) {
			return len;
		}
		str = str.trim();
		if (str.length() < 1) {
			return len;
		}
		char[] arr = str.toCharArray();
		int size = arr.length;
		for (int i = 0; i < size; i++) {
			if (isChinese(arr[i]) || isJapaneseChar(arr[i]) || isKoreaChar(arr[i]))
				len += 2;
			else
				len++;
		}
		return len;
	}

	/**
	 * 是否为中文字符
	 */
	private static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
			return true;
		}
		return false;
	}

	/**
	 * 是否为日文
	 * 
	 * @param c
	 * @return
	 */
	private static boolean isJapaneseChar(char c) {
		return mJapaneseUnicodeBlocks.contains(Character.UnicodeBlock.of(c));
	}

	/**
	 * 判断是否为韩文
	 * 
	 * @param c
	 * @return
	 */
	private static boolean isKoreaChar(char c) {
		if (!((c > 0x3130 && c < 0x318F) || (c >= 0xAC00 && c <= 0xD7A3))) {
			return false;
		}
		return true;
	}

	/**
	 * 字符串比较是否一致，空值跟null不一致
	 */
	public static boolean stringEquals(String value1, String value2) {
		boolean result = false;
		if (null == value1) {
			if (null == value2) {
				result = true;
			} else {
				result = false;
			}
		} else {
			result = value1.equals(value2);
		}
		return result;
	}

	/**
	 * 安全转数字
	 */
	public static int string2intSafe(String value, int defaultValue) {
		int result;
		try {
			result = Integer.parseInt(value);
		} catch (NumberFormatException e) {
			result = defaultValue;
		}
		return result;
	}

	/**
	 * 安全转数字
	 */
	public static long string2longSafe(String value, long defaultValue) {
		long result;
		try {
			result = Long.parseLong(value);
		} catch (NumberFormatException e) {
			result = defaultValue;
		}
		return result;
	}

	/**
	 * 转换编码
	 */
	public static String autoToUtf8(String str) {
		if (null == str) {
			return null;
		}
		String newStr = new String(str.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
		if (str.length() == newStr.length()) {
			return str;
		}
		return newStr;
	}
}
